const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const cors = require('cors');
const path = require('path');
const { spawn, exec } = require('child_process');

// 创建Express应用
const app = express();
const server = http.createServer(app);

// 启用CORS
app.use(cors());

// 提供静态文件
app.use(express.static(path.join(__dirname)));

// 创建WebSocket服务器
const wss = new WebSocket.Server({ server });

// 存储连接的客户端
let connectedClients = new Set();

// 投屏进程
let scrcpyProcess = null;
let ffmpegProcess = null;

// WebSocket连接处理
wss.on('connection', (ws) => {
    console.log('新的WebSocket客户端连接');
    connectedClients.add(ws);

    // 处理来自前端的消息
    ws.on('message', (message) => {
        try {
            const data = JSON.parse(message);
            handleClientMessage(data, ws);
        } catch (error) {
            console.error('解析客户端消息失败:', error);
        }
    });

    // 客户端断开连接
    ws.on('close', () => {
        console.log('WebSocket客户端断开连接');
        connectedClients.delete(ws);
    });

    // 发送连接成功消息
    ws.send(JSON.stringify({
        type: 'status',
        message: '连接成功',
        timestamp: Date.now()
    }));
});

// 处理客户端消息
function handleClientMessage(data, ws) {
    switch (data.type) {
        case 'touch':
            handleTouchEvent(data, ws);
            break;
        case 'key':
            handleKeyEvent(data, ws);
            break;
        case 'scroll':
            handleScrollEvent(data, ws);
            break;
        case 'start_scrcpy':
            startScrcpy(data, ws);
            break;
        case 'stop_scrcpy':
            stopScrcpy(ws);
            break;
        default:
            console.log('未知消息类型:', data.type);
    }
}

// 启动Scrcpy
async function startScrcpy(data, ws) {
    try {
        if (scrcpyProcess) {
            await stopScrcpy(ws);
        }

        console.log('正在启动Scrcpy...');
        
        // 检查ADB设备连接
        const devices = await checkAdbDevices();
        if (devices.length === 0) {
            throw new Error('未检测到ADB设备，请确保设备已连接并启用USB调试');
        }

        // 启动scrcpy进程
        const maxSize = data.maxSize || 1080;
        
        try {
            // 检查scrcpy命令是否存在
            const { execSync } = require('child_process');
            try {
                execSync('scrcpy --version', { stdio: 'ignore' });
                console.log('Scrcpy命令可用');
            } catch (versionError) {
                console.error('Scrcpy命令不可用:', versionError.message);
                // 直接启动回退视频流
                startFallbackVideoStream();
                
                ws.send(JSON.stringify({
                    type: 'scrcpy_response',
                    success: false,
                    message: 'Scrcpy命令不可用，使用回退模式'
                }));
                return;
            }
            
            scrcpyProcess = spawn('scrcpy', [
                '--max-size', maxSize.toString()
            ]);
            
            console.log('Scrcpy进程创建成功');
        } catch (spawnError) {
            console.error('创建Scrcpy进程失败:', spawnError);
            // 如果scrcpy启动失败，直接启动回退视频流
            startFallbackVideoStream();
            
            ws.send(JSON.stringify({
                type: 'scrcpy_response',
                success: false,
                message: 'Scrcpy启动失败，使用回退模式'
            }));
            return;
        }

        scrcpyProcess.stdout.on('data', (data) => {
            console.log('Scrcpy输出数据，大小:', data.length, '字节');
            
            // 检查是否是H.264视频数据
            if (data.length > 0) {
                try {
                    // 将H.264数据转换为base64
                    const base64Data = data.toString('base64');
                    
                    // 发送给所有连接的客户端
                    const videoMessage = {
                        type: 'video_frame',
                        data: `data:video/h264;base64,${base64Data}`,
                        width: 1080,
                        height: 1920,
                        timestamp: Date.now()
                    };
                    
                    console.log('发送H.264视频帧，大小:', data.length, '字节');
                    broadcastToClients(videoMessage);
                    
                } catch (error) {
                    console.error('处理H.264视频数据失败:', error);
                }
            }
        });

        scrcpyProcess.stderr.on('data', (data) => {
            console.log('Scrcpy错误:', data.toString());
        });

        scrcpyProcess.on('close', (code) => {
            console.log('Scrcpy进程已关闭，退出码:', code);
            scrcpyProcess = null;
            
            broadcastToClients({
                type: 'scrcpy_status',
                status: 'stopped',
                message: '投屏进程已停止'
            });
        });

        scrcpyProcess.on('error', (error) => {
            console.error('Scrcpy进程错误:', error);
            broadcastToClients({
                type: 'scrcpy_status',
                status: 'error',
                message: `Scrcpy错误: ${error.message}`
            });
        });

        // 添加进程启动检查
        console.log('Scrcpy进程启动，PID:', scrcpyProcess.pid);
        console.log('Scrcpy进程状态:', scrcpyProcess.connected);

        // 检查scrcpy是否成功启动
        let startupCheck = setInterval(() => {
            if (scrcpyProcess && scrcpyProcess.pid) {
                // scrcpy正在运行
                clearInterval(startupCheck);
                console.log('Scrcpy启动成功，PID:', scrcpyProcess.pid);
                
                // 等待一段时间，如果scrcpy没有输出视频数据，就启动回退视频流
                setTimeout(() => {
                    console.log('启动回退视频流...');
                    startFallbackVideoStream();
                }, 2000);
                
                // 立即发送状态更新
                broadcastToClients({
                    type: 'scrcpy_status',
                    status: 'connected',
                    message: '投屏已启动'
                });
                
                ws.send(JSON.stringify({
                    type: 'scrcpy_response',
                    success: true,
                    message: 'Scrcpy启动成功'
                }));
            }
        }, 1000); // 每1秒检查一次

    } catch (error) {
        console.error('启动Scrcpy失败:', error);
        ws.send(JSON.stringify({
            type: 'scrcpy_response',
            success: false,
            message: `启动失败: ${error.message}`
        }));
    }
}

// 停止Scrcpy
async function stopScrcpy(ws) {
    try {
        if (scrcpyProcess) {
            scrcpyProcess.kill('SIGTERM');
            scrcpyProcess = null;
            console.log('Scrcpy已停止');
            
            broadcastToClients({
                type: 'scrcpy_status',
                status: 'stopped',
                message: '投屏已停止'
            });
        }
        
        ws.send(JSON.stringify({
            type: 'scrcpy_response',
            success: true,
            message: 'Scrcpy已停止'
        }));
    } catch (error) {
        console.error('停止Scrcpy失败:', error);
        ws.send(JSON.stringify({
            type: 'scrcpy_response',
            success: false,
            message: `停止失败: ${error.message}`
        }));
    }
}

// 检查ADB设备
function checkAdbDevices() {
    return new Promise((resolve, reject) => {
        exec('adb devices', (error, stdout, stderr) => {
            if (error) {
                reject(error);
                return;
            }
            
            const lines = stdout.toString().split('\n');
            const devices = [];
            
            for (const line of lines) {
                if (line.includes('\tdevice')) {
                    const deviceId = line.split('\t')[0];
                    devices.push(deviceId);
                }
            }
            
            resolve(devices);
        });
    });
}

// 处理触摸事件
function handleTouchEvent(data, ws) {
    console.log('收到触摸事件:', data);
    
    if (!scrcpyProcess) {
        console.log('Scrcpy未启动，无法处理触摸事件');
        ws.send(JSON.stringify({
            type: 'touch_response',
            success: false,
            message: 'Scrcpy未启动'
        }));
        return;
    }

    try {
        // 使用adb shell input命令发送触摸事件
        const x = Math.round(data.x);
        const y = Math.round(data.y);
        
        console.log(`处理触摸事件: ${data.action} at (${x}, ${y})`);
        
        let command;
        if (data.action === 'down') {
            command = `adb shell input touchscreen swipe ${x} ${y} ${x} ${y} 100`;
        } else if (data.action === 'move') {
            // 触摸移动，可以用于拖拽
            command = `adb shell input touchscreen swipe ${x} ${y} ${x} ${y} 50`;
        } else if (data.action === 'scroll') {
            // 滚动事件
            command = `adb shell input touchscreen swipe ${x} ${y} ${x} ${y + 100} 200`;
        } else if (data.action === 'up') {
            // 触摸抬起不需要额外命令
            command = null;
        }

        if (command) {
            console.log('执行ADB命令:', command);
            exec(command, (error, stdout, stderr) => {
                if (error) {
                    console.error('触摸事件执行失败:', error);
                    ws.send(JSON.stringify({
                        type: 'touch_response',
                        success: false,
                        message: error.message
                    }));
                } else {
                    console.log('触摸事件执行成功');
                    ws.send(JSON.stringify({
                        type: 'touch_response',
                        success: true,
                        x: x,
                        y: y,
                        timestamp: Date.now()
                    }));
                }
            });
        } else {
            ws.send(JSON.stringify({
                type: 'touch_response',
                success: true,
                x: x,
                y: y,
                timestamp: Date.now()
            }));
        }
    } catch (error) {
        console.error('发送触摸事件失败:', error);
        ws.send(JSON.stringify({
            type: 'touch_response',
            success: false,
            message: error.message
        }));
    }
}

// 处理按键事件
function handleKeyEvent(data, ws) {
    if (!scrcpyProcess) {
        ws.send(JSON.stringify({
            type: 'key_response',
            success: false,
            message: 'Scrcpy未启动'
        }));
        return;
    }

    try {
        // 使用adb shell input命令发送按键事件
        const keyCode = data.keyCode || 0;
        const command = `adb shell input keyevent ${keyCode}`;
        
        exec(command, (error, stdout, stderr) => {
            if (error) {
                console.error('按键事件执行失败:', error);
                ws.send(JSON.stringify({
                    type: 'key_response',
                    success: false,
                    message: error.message
                }));
            } else {
                ws.send(JSON.stringify({
                    type: 'key_response',
                    success: true,
                    key: data.key,
                    timestamp: Date.now()
                }));
            }
        });
    } catch (error) {
        console.error('发送按键事件失败:', error);
        ws.send(JSON.stringify({
            type: 'key_response',
            success: false,
            message: error.message
        }));
    }
}

// 处理滚动事件
function handleScrollEvent(data, ws) {
    if (!scrcpyProcess) {
        ws.send(JSON.stringify({
            type: 'scroll_response',
            success: false,
            message: 'Scrcpy未启动'
        }));
        return;
    }

    try {
        // 使用adb shell input命令发送滚动事件
        const deltaX = data.deltaX || 0;
        const deltaY = data.deltaY || 0;
        
        // 模拟滚动（通过触摸滑动实现）
        const startX = 500;
        const startY = 500;
        const endX = startX + deltaX;
        const endY = startY + deltaY;
        
        const command = `adb shell input touchscreen swipe ${startX} ${startY} ${endX} ${endY} 200`;
        
        exec(command, (error, stdout, stderr) => {
            if (error) {
                console.error('滚动事件执行失败:', error);
                ws.send(JSON.stringify({
                    type: 'scroll_response',
                    success: false,
                    message: error.message
                }));
            } else {
                ws.send(JSON.stringify({
                    type: 'scroll_response',
                    success: true,
                    deltaX: deltaX,
                    deltaY: deltaY,
                    timestamp: Date.now()
                }));
            }
        });
    } catch (error) {
        console.error('发送滚动事件失败:', error);
        ws.send(JSON.stringify({
            type: 'scroll_response',
            success: false,
            message: error.message
        }));
    }
}

// 启动视频流处理
function startVideoStream() {
    try {
        console.log('启动视频流处理...');
        
        // 连接到scrcpy的网络端口
        const net = require('net');
        const client = new net.Socket();
        
        client.connect(27183, '127.0.0.1', () => {
            console.log('已连接到scrcpy端口27183');
            
            // 发送视频流请求
            client.write('GET /video HTTP/1.1\r\n\r\n');
        });
        
        client.on('data', (data) => {
            try {
                // 将H.264数据转换为base64
                const base64Data = data.toString('base64');
                
                // 发送给所有连接的客户端
                const videoMessage = {
                    type: 'video_frame',
                    data: `data:video/h264;base64,${base64Data}`,
                    width: 1080,
                    height: 1920,
                    timestamp: Date.now()
                };
                
                console.log('发送H.264视频帧，大小:', data.length, '字节');
                broadcastToClients(videoMessage);
                
            } catch (error) {
                console.error('处理视频数据失败:', error);
            }
        });
        
        client.on('error', (error) => {
            console.error('视频流连接错误:', error);
            // 如果网络连接失败，回退到模拟视频流
            startFallbackVideoStream();
        });
        
        client.on('close', () => {
            console.log('视频流连接已关闭');
        });
        
    } catch (error) {
        console.error('启动视频流失败:', error);
        // 回退到模拟视频流
        startFallbackVideoStream();
    }
}

// 回退视频流（如果网络连接失败）
function startFallbackVideoStream() {
    console.log('启动回退视频流...');
    
    const videoInterval = setInterval(() => {
        try {
            const width = 320;
            const height = 640;
            const canvas = require('canvas').createCanvas(width, height);
            const ctx = canvas.getContext('2d');
            
            // 绘制当前时间
            ctx.fillStyle = '#000';
            ctx.fillRect(0, 0, width, height);
            
            ctx.fillStyle = '#fff';
            ctx.font = '20px Arial';
            ctx.fillText(`投屏中 - ${new Date().toLocaleTimeString()}`, 20, 40);
            
            // 绘制一些测试元素
            ctx.fillStyle = '#007bff';
            ctx.fillRect(50, 100, 100, 50);
            ctx.fillStyle = '#28a745';
            ctx.fillRect(200, 100, 100, 50);
            
            // 添加设备信息
            ctx.fillStyle = '#ffc107';
            ctx.fillText('OnePlus PJE110', 20, 80);
            ctx.fillText('Android 15', 20, 100);
            
            // 转换为base64
            const dataURL = canvas.toDataURL('image/jpeg', 0.8);
            
            // 发送给所有连接的客户端
            const videoMessage = {
                type: 'video_frame',
                data: dataURL,
                width: width,
                height: height,
                timestamp: Date.now()
            };
            
            broadcastToClients(videoMessage);
            
        } catch (frameError) {
            console.error('生成回退视频帧失败:', frameError);
        }
    }, 100); // 10 FPS
    
    console.log('回退视频流已启动');
}

// 广播消息给所有客户端
function broadcastToClients(message) {
    console.log('广播消息给客户端，类型:', message.type, '客户端数量:', connectedClients.size);
    
    let sentCount = 0;
    connectedClients.forEach(client => {
        if (client.readyState === WebSocket.OPEN) {
            try {
                client.send(JSON.stringify(message));
                sentCount++;
            } catch (error) {
                console.error('发送消息到客户端失败:', error);
            }
        } else {
            console.log('客户端WebSocket状态:', client.readyState);
        }
    });
    
    console.log('成功发送给', sentCount, '个客户端');
}

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
    console.log('WebSocket服务器已启动');
    console.log('等待投屏连接...');
});

// 优雅关闭
process.on('SIGINT', async () => {
    console.log('正在关闭服务器...');
    if (scrcpyProcess) {
        await stopScrcpy();
    }
    server.close(() => {
        console.log('服务器已关闭');
        process.exit(0);
    });
});